package com.channel.connector.ctripos.service.impl;

import com.alibaba.fastjson.JSON;
import com.channel.connector.ctripos.common.constant.InitData;
import com.channel.connector.ctripos.domain.CtriposShopInfoDO;
import com.channel.connector.ctripos.service.CtripOSRemoteInvokeService;
import com.channel.connector.ctripos.webservice.confirmnum.ErrorsType;
import com.channel.connector.ctripos.webservice.confirmnum.HotelResNumUpdateSoap;
import com.channel.connector.ctripos.webservice.confirmnum.OTAHotelResNumUpdateRQ;
import com.channel.connector.ctripos.webservice.confirmnum.OTAHotelResNumUpdateRS;
import com.channel.connector.ctripos.webservice.dynamic.OTAHotelAvailNotifRQ;
import com.channel.connector.ctripos.webservice.dynamic.OTAHotelAvailNotifRS;
import com.channel.connector.ctripos.webservice.dynamic.OTAHotelRateAmountNotifRQ;
import com.channel.connector.ctripos.webservice.dynamic.OTAHotelRateAmountNotifRS;
import com.channel.connector.ctripos.webservice.dynamic.OTAReceiveServiceSoap;
import com.channel.connector.ctripos.webservice.staticinfo.ErrorType;
import com.channel.connector.ctripos.webservice.staticinfo.HotelStaticInfoServiceSoap;
import com.channel.connector.ctripos.webservice.staticinfo.OTAHotelDescriptiveContentNotifRQ;
import com.channel.connector.ctripos.webservice.staticinfo.OTAHotelDescriptiveContentNotifRS;
import com.channel.connector.ctripos.webservice.staticinfo.OTAHotelInvNotifRQ;
import com.channel.connector.ctripos.webservice.staticinfo.OTAHotelInvNotifRS;
import com.channel.connector.ctripos.webservice.staticinfo.OTAHotelRatePlanNotifRQ;
import com.channel.connector.ctripos.webservice.staticinfo.OTAHotelRatePlanNotifRS;
import com.channel.connector.ctripos.webservice.staticinfo.OTAHotelStatsNotifRQ;
import com.channel.connector.ctripos.webservice.staticinfo.OTAHotelStatsNotifRS;
import lombok.extern.slf4j.Slf4j;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by ASUS on 2018/11/15.
 */
@Service("ctripOSRemoteInvokeService")
@Slf4j
public class CtripOSRemoteInvokeServiceImpl implements CtripOSRemoteInvokeService {

    @Override
    public Map<Long, OTAHotelDescriptiveContentNotifRS> pushHotelInfo(Map<Long, OTAHotelDescriptiveContentNotifRQ> hotelDescriptiveContentNotifRQMap, String shopId) {
        if (null == hotelDescriptiveContentNotifRQMap || hotelDescriptiveContentNotifRQMap.size() <= 0) {
            return null;
        }
        final CtriposShopInfoDO shopInfoDO = InitData.shopIdShopMap.get(shopId);
        if (null == shopInfoDO) {
            log.error("getCtripOSAuthConfig has error,shopId:" + shopId);
            return null;
        }
        Map<Long, OTAHotelDescriptiveContentNotifRS> returnMap = new HashMap<>();

        JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
        jaxWsProxyFactoryBean.setServiceClass(HotelStaticInfoServiceSoap.class);
        jaxWsProxyFactoryBean.setAddress(shopInfoDO.getStaticinfoUrl());
        HotelStaticInfoServiceSoap hotelStaticInfoServiceSoap = (HotelStaticInfoServiceSoap) jaxWsProxyFactoryBean.create();
        for (Map.Entry<Long, OTAHotelDescriptiveContentNotifRQ> m : hotelDescriptiveContentNotifRQMap.entrySet()) {
            Date start = new Date();
            OTAHotelDescriptiveContentNotifRS otaHotelDescriptiveContentNotifR = null;
            try {
                otaHotelDescriptiveContentNotifR = hotelStaticInfoServiceSoap.hotelDescriptiveContentNotif(m.getValue());
                returnMap.put(m.getKey(), otaHotelDescriptiveContentNotifR);
            } catch (Exception e) {
                log.error("pushHotelInfo has error,param:" + JSON.toJSONString(m.getValue()), e);
                otaHotelDescriptiveContentNotifR = new OTAHotelDescriptiveContentNotifRS();
                ErrorType errorType = new ErrorType();
                errorType.setCode("Error");
                errorType.setShortText(e.getMessage());
                otaHotelDescriptiveContentNotifR.setError(errorType);
                returnMap.put(m.getKey(), otaHotelDescriptiveContentNotifR);
            } finally {
                log.info("pushHotelInfo param: {}, response: {}", JSON.toJSON(m.getValue()), JSON.toJSONString(otaHotelDescriptiveContentNotifR));
            }
        }
        return returnMap;
    }

    @Override
    public Map<Long, OTAHotelInvNotifRS> pushRoomTypeInfo(Map<Long, OTAHotelInvNotifRQ> hotelInvNotifRQMap, String shopId) {
        if (null == hotelInvNotifRQMap || hotelInvNotifRQMap.size() <= 0) {
            return null;
        }
        final CtriposShopInfoDO shopInfoDO = InitData.shopIdShopMap.get(shopId);
        if (null == shopInfoDO) {
            log.error("getCtripOSAuthConfig has error,shopId:" + shopId);
            return null;
        }
        Map<Long, OTAHotelInvNotifRS> returnMap = new HashMap<>();

        JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
        jaxWsProxyFactoryBean.setServiceClass(HotelStaticInfoServiceSoap.class);
        jaxWsProxyFactoryBean.setAddress(shopInfoDO.getStaticinfoUrl());
        HotelStaticInfoServiceSoap hotelStaticInfoServiceSoap = (HotelStaticInfoServiceSoap) jaxWsProxyFactoryBean.create();

        for (Map.Entry<Long, OTAHotelInvNotifRQ> m : hotelInvNotifRQMap.entrySet()) {
            Date start = new Date();
            OTAHotelInvNotifRS hotelInvNotifRS = null;
            try {
                hotelInvNotifRS = hotelStaticInfoServiceSoap.hotelInvNotif(m.getValue());
                returnMap.put(m.getKey(), hotelInvNotifRS);
            } catch (Exception e) {
                log.error("pushRoomTypeInfo has error,param:" + JSON.toJSONString(m.getValue()), e);
                hotelInvNotifRS = new OTAHotelInvNotifRS();
                ErrorType errorType = new ErrorType();
                errorType.setCode("Error");
                errorType.setShortText(e.getMessage());
                hotelInvNotifRS.setError(errorType);
                returnMap.put(m.getKey(), hotelInvNotifRS);
            } finally {
                log.info("pushRoomTypeInfo param: {}, response: {}", JSON.toJSON(m.getValue()), JSON.toJSONString(hotelInvNotifRS));
            }
        }
        return returnMap;
    }

    @Override
    public Map<Long, OTAHotelRatePlanNotifRS> pushRatePlanInfo(Map<Long, OTAHotelRatePlanNotifRQ> hotelRatePlanNotifRQMap, String shopId) {
        if (null == hotelRatePlanNotifRQMap || hotelRatePlanNotifRQMap.size() <= 0) {
            return null;
        }
        final CtriposShopInfoDO shopInfoDO = InitData.shopIdShopMap.get(shopId);
        if (null == shopInfoDO) {
            log.error("getCtripOSAuthConfig has error,shopId:" + shopId);
            return null;
        }
        Map<Long, OTAHotelRatePlanNotifRS> returnMap = new HashMap<>();

        JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
        jaxWsProxyFactoryBean.setServiceClass(HotelStaticInfoServiceSoap.class);
        jaxWsProxyFactoryBean.setAddress(shopInfoDO.getStaticinfoUrl());
        HotelStaticInfoServiceSoap hotelStaticInfoServiceSoap = (HotelStaticInfoServiceSoap) jaxWsProxyFactoryBean.create();

        for (Map.Entry<Long, OTAHotelRatePlanNotifRQ> m : hotelRatePlanNotifRQMap.entrySet()) {
            Date start = new Date();
            OTAHotelRatePlanNotifRS hotelRatePlanNotifRS = null;
            try {
                hotelRatePlanNotifRS = hotelStaticInfoServiceSoap.hotelRatePlanNotif(m.getValue());
                returnMap.put(m.getKey(), hotelRatePlanNotifRS);
            } catch (Exception e) {
                log.error("pushRatePlanInfo has error,param:" + JSON.toJSONString(m.getValue()), e);
                hotelRatePlanNotifRS = new OTAHotelRatePlanNotifRS();
                ErrorType errorType = new ErrorType();
                errorType.setCode("Error");
                errorType.setShortText(e.getMessage());
                hotelRatePlanNotifRS.setError(errorType);
                returnMap.put(m.getKey(), hotelRatePlanNotifRS);
            } finally {
                log.info("pushRatePlanInfo param: {}, response: {}", JSON.toJSON(m.getValue()), JSON.toJSONString(hotelRatePlanNotifRS));
            }
        }
        return returnMap;
    }

    @Override
    public OTAHotelStatsNotifRS syncHotelInfo(OTAHotelStatsNotifRQ otaHotelStatsNotifRQ, String shopId) {
        Date start = new Date();
        final CtriposShopInfoDO shopInfoDO = InitData.shopIdShopMap.get(shopId);
        if (null == shopInfoDO) {
            log.error("getCtripOSAuthConfig has error,shopId:" + shopId);
            return null;
        }
        JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
        jaxWsProxyFactoryBean.setServiceClass(HotelStaticInfoServiceSoap.class);
        jaxWsProxyFactoryBean.setAddress(shopInfoDO.getStaticinfoUrl());
        HotelStaticInfoServiceSoap hotelStaticInfoServiceSoap = (HotelStaticInfoServiceSoap) jaxWsProxyFactoryBean.create();
        OTAHotelStatsNotifRS otaHotelStatsNotifR = null;
        try {
            otaHotelStatsNotifR = hotelStaticInfoServiceSoap.hotelStatsNotif(otaHotelStatsNotifRQ);
        } catch (Exception e) {
            log.error("syncHotelInfo has error.");
            if (null == otaHotelStatsNotifR) {
                otaHotelStatsNotifR = new OTAHotelStatsNotifRS();
            }
            ErrorType errorType = new ErrorType();
            errorType.setCode("Error");
            errorType.setShortText(e.getMessage());

            List<Object> tpaExtensionsOrSuccessOrError = new ArrayList<>();
            tpaExtensionsOrSuccessOrError.add(errorType);
            otaHotelStatsNotifR.setTpaExtensionsOrSuccessOrError(tpaExtensionsOrSuccessOrError);
        } finally {
            log.info("syncHotelInfo param: {}, response: {}", JSON.toJSON(otaHotelStatsNotifRQ), JSON.toJSONString(otaHotelStatsNotifR));
        }
        return otaHotelStatsNotifR;
    }

    @Override
    public OTAHotelAvailNotifRS pushAvailabilityAndInventory(OTAHotelAvailNotifRQ otaHotelAvailNotifRQ, String shopId) {
        Date start = new Date();
        final CtriposShopInfoDO shopInfoDO = InitData.shopIdShopMap.get(shopId);
        if (null == shopInfoDO) {
            log.error("getCtripOSAuthConfig has error,shopId:" + shopId);
            return null;
        }
        OTAHotelAvailNotifRS otaHotelAvailNotifRS = null;
        try {
            JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
            jaxWsProxyFactoryBean.setServiceClass(OTAReceiveServiceSoap.class);
            jaxWsProxyFactoryBean.setAddress(shopInfoDO.getDynamicinfoUrl());
            OTAReceiveServiceSoap otaReceiveServiceSoap = (OTAReceiveServiceSoap) jaxWsProxyFactoryBean.create();
            otaHotelAvailNotifRS = otaReceiveServiceSoap.hotelAvailNotif(otaHotelAvailNotifRQ);
        } catch (Exception e) {
            log.error("pushAvailabilityAndInventory has error.");
            ErrorType errorType = new ErrorType();
            errorType.setCode("Error");
            errorType.setShortText(e.getMessage());

            otaHotelAvailNotifRS = new OTAHotelAvailNotifRS();
            List<Object> tpaExtensionsOrSuccessOrError = new ArrayList<>();
            tpaExtensionsOrSuccessOrError.add(errorType);
            otaHotelAvailNotifRS.setWarningsOrErrorsOrSuccess(tpaExtensionsOrSuccessOrError);
        } finally {
            log.info("pushAvailabilityAndInventory param: {}, response: {}", JSON.toJSON(otaHotelAvailNotifRQ), JSON.toJSONString(otaHotelAvailNotifRS));
        }
        return otaHotelAvailNotifRS;
    }

    @Override
    public OTAHotelRateAmountNotifRS pushRate(OTAHotelRateAmountNotifRQ otaHotelRateAmountNotifRQ, String shopId) {
        Date start = new Date();
        final CtriposShopInfoDO shopInfoDO = InitData.shopIdShopMap.get(shopId);
        if (null == shopInfoDO) {
            log.error("getCtripOSAuthConfig has error,shopId:" + shopId);
            return null;
        }
        OTAHotelRateAmountNotifRS otaHotelRateAmountNotifRS = null;
        try {
            JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
            jaxWsProxyFactoryBean.setServiceClass(OTAReceiveServiceSoap.class);
            jaxWsProxyFactoryBean.setAddress(shopInfoDO.getDynamicinfoUrl());
            OTAReceiveServiceSoap otaReceiveServiceSoap = (OTAReceiveServiceSoap) jaxWsProxyFactoryBean.create();
            otaHotelRateAmountNotifRS = otaReceiveServiceSoap.hotelRateAmountNotif(otaHotelRateAmountNotifRQ);
        } catch (Exception e) {
            log.error("pushRate has error.");
            ErrorType errorType = new ErrorType();
            errorType.setCode("Error");
            errorType.setShortText(e.getMessage());

            otaHotelRateAmountNotifRS = new OTAHotelRateAmountNotifRS();
            List<Object> tpaExtensionsOrSuccessOrError = new ArrayList<>();
            tpaExtensionsOrSuccessOrError.add(errorType);
            otaHotelRateAmountNotifRS.setWarningsOrErrorsOrSuccess(tpaExtensionsOrSuccessOrError);
        } finally {
            log.info("pushRate param: {}, response: {}", JSON.toJSON(otaHotelRateAmountNotifRQ), JSON.toJSONString(otaHotelRateAmountNotifRS));
        }
        return otaHotelRateAmountNotifRS;
    }

    @Override
    public OTAHotelResNumUpdateRS updateResConfirmationNum(OTAHotelResNumUpdateRQ otaHotelResNumUpdateRQ, String shopId) {
        Date start = new Date();
        final CtriposShopInfoDO shopInfoDO = InitData.shopIdShopMap.get(shopId);
        if (null == shopInfoDO) {
            log.error("getCtripOSAuthConfig has error,shopId:" + shopId);
            return null;
        }
        OTAHotelResNumUpdateRS otaHotelResNumUpdateRS = null;
        try {
            JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
            jaxWsProxyFactoryBean.setServiceClass(HotelResNumUpdateSoap.class);
            jaxWsProxyFactoryBean.setAddress(shopInfoDO.getConfirmNumUrl());
            HotelResNumUpdateSoap soap = (HotelResNumUpdateSoap) jaxWsProxyFactoryBean.create();
            otaHotelResNumUpdateRS = soap.request(otaHotelResNumUpdateRQ);

        } catch (Exception e) {
            log.error("updateResConfirmationNum has error.", e);
            ErrorsType errorsType = new ErrorsType();
            List<ErrorsType.Error> errors = new ArrayList<>();
            ErrorsType.Error error = new ErrorsType.Error();
            error.setCode("Error");
            error.setShortText(e.getMessage());
            errors.add(error);
            errorsType.setError(errors);

            otaHotelResNumUpdateRS = new OTAHotelResNumUpdateRS();
            otaHotelResNumUpdateRS.setErrors(errorsType);
        } finally {
            log.info("updateResConfirmationNum param: {}, response: {}", JSON.toJSON(otaHotelResNumUpdateRQ), JSON.toJSONString(otaHotelResNumUpdateRS));
        }
        return otaHotelResNumUpdateRS;
    }
}
